Skip to content

feat(device): optimize parse_dtb with a generic hash map#269

Merged
daniel-rossier merged 1 commit into
mainfrom
feat-device-optimize-parse_dtb-function
Jul 7, 2026
Merged

feat(device): optimize parse_dtb with a generic hash map#269
daniel-rossier merged 1 commit into
mainfrom
feat-device-optimize-parse_dtb-function

Conversation

@daniel-rossier

Copy link
Copy Markdown
Contributor

Closes #85

Problem

parse_dtb() matched every device tree node against the registered drivers with a nested loop: for each of the N nodes it walked the whole list of M drivers looking for a matching compatible string, once per initcall level — an O(N·M) scan.

Change

  • Introduce a generic string-keyed hash map (lib/hashmap.c, include/hashmap.h): open addressing with linear probing, automatic growth, copied/owned keys, void * values. A reusable container other subsystems can rely on.
  • Use it in parse_dtb() to index the drivers by their compatible string. The map is built once in O(M); the device tree is then scanned a single time and each node is matched in O(1), bringing the parsing down to O(N + M).
  • Matched nodes are queued per initcall level during the single scan and only initialized afterwards — core drivers before postcore ones and in device tree order within each level — so the initialization order is unchanged.
  • A single scratch dev_t is reused while probing nodes instead of being allocated and freed for every visited node.

Behaviour

Initialization order is identical. The only theoretical difference is a compatible registered at both CORE and POSTCORE: the old code initialized such a node twice (a latent double-init), the new code once at core level. This cannot happen with the current drivers — the CORE and POSTCORE compatible sets are disjoint.

Verification

  • Builds cleanly (virt64_defconfig); device.o and hashmap.o compile with no new warnings; clang-format reports no diff on the touched files.
  • Host equivalence test comparing the old O(N·M) and new O(N+M) matching: identical init order on all realistic cases (interleaved DT, postcore-only, disabled/absent nodes, no drivers).
  • Host functional test of lib/hashmap.c: 500 inserts triggering several rehashes, exact-pointer lookups, overwrite semantics, copied-key ownership.

@daniel-rossier daniel-rossier force-pushed the feat-device-optimize-parse_dtb-function branch from f4fdea2 to 7506cba Compare July 7, 2026 16:22
parse_dtb() matched every device tree node against the registered drivers
with a nested loop: for each of the N nodes it walked the whole list of M
drivers looking for a compatible string, once per initcall level -- an
O(N * M) scan.

Introduce a generic string-keyed hash map (lib/hashmap.c, include/hashmap.h)
and use it to index the drivers by their compatible string. The map is built
once in O(M); the device tree is then scanned a single time and each node is
matched in O(1), bringing the parsing down to O(N + M). The hash map is a
reusable container (open addressing, automatic growth, copied keys) that other
subsystems can rely on. Its "round up to a power of two" helper is exposed as a
generic round_up_pow2() in the new include/math.h.

Matched nodes are queued per initcall level during the single scan and only
initialized afterwards, core drivers before postcore ones and in device tree
order within each level, so the initialization order is unchanged. A single
scratch dev_t is reused while probing nodes instead of being allocated and
freed for every visited node.

Closes #85
@daniel-rossier daniel-rossier force-pushed the feat-device-optimize-parse_dtb-function branch from 7506cba to cbc6b53 Compare July 7, 2026 16:27
@daniel-rossier daniel-rossier merged commit a6e4352 into main Jul 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(device): optimize parse_dtb function

1 participant